home *** CD-ROM | disk | FTP | other *** search
- /* CPROG15.CPP - List all filenames+attributes in the current directory */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <dos.h>
- #include <dir.h>
- #include <string.h>
-
-
- //---------------------------------------------------------------------------
- /* The next function converts an attribute number into a string that shows
- more clearly which attribute flags have been set. It expects a single-byte
- file attribute and returns a pointer to the string. An attribute byte is
- bit-significant in that when its value is written in binary notation, the
- fifth bit from the right, for example, indicates whether or not the file
- is a subdirectory. 1 says it is, 0 says it isn't. Another example:
- File attribute=decimal 33. Binary=100001. Bit zero (the one on the right) when
- turned on says the file is read-only. Bit five (count from right to left,
- starting at zero) when turned on says this file hasn't been backed up
- (archived). The letters in the array attlet[] indicateethe meaning of the bit
- in that position when it is turned on.*/
-
- char *makestring(char fileattribute)
- {
- static char attstring[7], // 6 attributes + '\0'. Static so that when
- // makestring() exits, returning a pointer
- // to attstring, attstring isn't destroyed.
- attlets[]= "ADLSHR"; // The letters used.
- int i; // A loop counter.
-
- for(i=5; i>=0; i--) // For each of the six significant bits...
- {
- attstring[i]= ( fileattribute & 1 ) ? attlets[i] : '-';
- // Logical AND the attribute with 1.
- // 1 AND 1 = 1 1 AND 0 = 0.
- // So the test is only non-zero if bit 0
- // is not zero. True result causes the
- // appropriate letter in attlets[] to be
- // put in attstring[]. False result gives '-'
- fileattribute=fileattribute >> 1;
- // The >> operator shifts all the bits to the
- // right by the number of places indicated by
- // the following number. eg: 11011 becomes
- // 1101 - the rightmost bit is lost. We do
- // this so that the bit we're interested in
- // is always in position zero, making the
- // fileattribute & 1 always the correct test.
- }
- attstring[6]='\0'; // terminate the string
- return( attstring ); // return its address for use as a pointer
- }
-
- //---------------------------------------------------------------------------
- int main(void)
- {
- struct ffblk filedetails; // Make a ffblk-type structure for findfirst()/findnext()
-
- struct filerecord { char filename[13]; // 8 + '.' + 3 + '\0' = 13 chars
- char attribute; // 1 byte for the attribute
- struct filerecord *previous; // Pointer to previous structure in chain of records. Will be 0 if this is top of list
- struct filerecord *next; // Pointer to next record in list. Will be 0 if this is bottom.
- };
- /* A filerecord-type structure has room for the filename, its attribute plus
- two structure pointers - one to the previous structure in the list,
- one to the next. */
-
- struct filerecord *firstrec, *temp, *current;
- // Could have included these in the declaration
- // of filerecord above. Did it as a separate
- // line for clarity. Current will hold a pointer
- // to whichever filerecord-type structure
- // we're dealing with currently. Firstrec will
- // point to the first in the list so we always
- // have a record of the start of the chain. Temp
- // is needed as a temporary place holder.
-
- /* Use findfirst()/findnext() to get list of files in current directory
- into memory. Create new storage records as required. */
-
- if( findfirst("*.*", &filedetails, FA_RDONLY+FA_HIDDEN+FA_SYSTEM+FA_LABEL+FA_DIREC+FA_ARCH) == -1 )
- {
- printf("Nothing to do!\n"); // Highly unlikely this would happen.
- exit(0);
- }
- /* Point of interest: in binary, 10000+00001=10001. 10001+00100=10101.
- Adding together all possible flags produces a number in which all
- flags are set on, so all files will be found - even the weird ones
- that are normally hidden. More about FA_RDONLY etc at bottom. */
-
- temp=firstrec=0; // 0 in firstrec later triggers its intialisation.
- // Temp needs to start out as zero - it will become
- // the first pointer to the previous structure. Since
- // the first structure has nowhere to point, putting
- // zero in *previous indictates to later program code
- // threading backwards up the chain that it has
- // reached the top.
-
- /* Neat bit of C++ syntax is that you can say x=y=z=number, and number
- goes into x, y and z. */
-
- // Read filenames, create and fill structures
- do {
- if( ! (current=new filerecord) ) // Make a new structure
- {
- printf("Oh dear, we're clean out of spare bytes!\n");
- exit(0);
- }
-
- if( firstrec == 0 )
- firstrec=current; // Initialise firstrec to point to
- // first strcucture in list.
-
- // Fill in the new record
- strcpy( current->filename, filedetails.ff_name ); // Copy name
- current->attribute = filedetails.ff_attrib; // Copy attribute
- current->previous=temp; // temp stores previous value of current
- if ( temp ) // If this isn't the top of the
- // list (ie temp is not zero) then...
- temp->next=current; // Make the previous *next pointer
- // point forward to this structure
- temp=current; // Make temp point here so that
- // next time round the loop we can
- // fill in the *next pointer.
-
- } while( ! findnext(&filedetails) ); // Loop while there are files
-
- current->next=0; // And end the chain.
- printf("A=Archive bit set D=Directory L=Volume Label S=System H=Hidden R=Read only");
-
- // Now print each record - loop while current is not zero
- for( current=firstrec; current; current=current->next )
- printf("%12s\tattribute:%s\n", current->filename, makestring(current->attribute) );
-
- /* %12s pads the filename with spaces to fill a field
- of 12 characters
- \t is a tab
- %s picks up pointer to attrstring[] returned
- by makestring */
-
- exit(-1);
- }
-
- /* NOTES
- 1: I found these #define values (set up in DOS.H) in the help system...
-
- FA_RDONLY Read-only attribute
- FA_HIDDEN Hidden file
- FA_SYSTEM System file
- FA_LABEL Volume label
- FA_DIREC Directory
- FA_ARCH Archive
-
- The attribute parameter for findfirst() filters out all files that
- haven't got the selected attribute set (except in the case of 0 which also
- picks up files that have just the attribute set. Adding togther all possible
- attributes gives all files.
- 2: It's all easier than it looks - strip out the comments and there isn't
- much code here.
- 3: Exercise for the reader: pause output a screen at a time, printing the
- help line each time round and a 'Press a key' message.
- */